﻿using System;
using System.Collections.Generic;
using System.Text;

namespace TYBase
{
    public static class ByteExtend
    {
        public static byte[] Append(this byte[] byteRead, byte[] data)
        {
            if (data == null)
                return data;
            if (byteRead == null)
            {
                return data;
            }
            byte[] dataTmp = new byte[byteRead.Length + data.Length];
            Array.Copy(byteRead, dataTmp, byteRead.Length);
            Array.Copy(data, 0, dataTmp, byteRead.Length, data.Length);
            return dataTmp;
        }

        public static int[] AsInt(this byte[] byteRead)
        {
            int intLen = byteRead.Length / 4;
            if (byteRead.Length % 4 != 0)
            {
                byteRead = byteRead.Append(new byte[4 - byteRead.Length % 4]);
                intLen++;
            }
            int[] retData = new int[intLen];
            for (int i = 0, j = 0; i < byteRead.Length; i += 4, j++)
            {
                retData[j] = BitConverter.ToInt32(byteRead, i);
            }
            return retData;
        }

        public static ushort[] AsUShort(this byte[] byteRead)
        {
            int intLen = byteRead.Length / 2;
            if (byteRead.Length % 2 != 0)
            {
                byteRead = byteRead.Append(new byte[2 - byteRead.Length % 2]);
                intLen++;
            }
            ushort[] retData = new ushort[intLen];
            for (int i = 0, j = 0; i < byteRead.Length; i += 2, j++)
            {
                retData[j] = BitConverter.ToUInt16(byteRead, i);
            }
            return retData;
        }

        public static byte[] AsBytes(this ushort[] shortData)
        {
            int intLen = shortData.Length * 2;
            byte[] retData = new byte[intLen];

            for (int i = 0, j = 0; i < shortData.Length; i ++, j+=2)
            {
                var bytes = BitConverter.GetBytes(shortData[i]);
                retData[j] = bytes[0];
                retData[j+1] = bytes[1];
            }
            return retData;
        }
        public static bool IsSame(this byte[] data1, byte[] data2)
        {
            if (data1 == null || data2 == null || data1.Length == 0 || data2.Length == 0 || data1.Length != data2.Length)
            {
                return false;
            }
            for (int i = 0; i < data1.Length; i++)
            {
                if (data1[i] != data2[i])
                    return false;
            }
            return true;
        }

        public static int Indexof(this byte[] datas, byte[] needle)
        {
            var len = needle.Length;
            var limit = datas.Length - len;
            for (var i = 0; i <= limit; i++)
            {
                var k = 0;
                for (; k < len; k++)
                {
                    if (needle[k] != datas[i + k]) break;
                }
                if (k == len)
                    return i;
            }
            return -1;
        }

        public static List<byte[]> Split(this byte[] datas, byte[] needle)
        {
            List<byte[]> listData = new List<byte[]>();
            byte[] dataLeft = datas;
            while (true)
            {
                var index = Indexof(dataLeft, needle);
                if (index > 0)
                {
                    byte[] dataTmp = new byte[index + needle.Length];
                    Array.Copy(dataLeft, dataTmp, dataTmp.Length);
                    listData.Add(dataTmp);
                    if (dataTmp.Length == dataLeft.Length)
                    {
                        return listData;
                    }
                    byte[] datatmp2 = new byte[dataLeft.Length - dataTmp.Length];
                    Array.Copy(dataLeft, dataTmp.Length, datatmp2, 0, datatmp2.Length);
                    dataLeft = datatmp2;
                }
                else
                {
                    listData.Add(dataLeft);
                    return listData;
                }
            }
        }

        public static string AsString(this byte[] data)
        {
            if (data == null || data.Length == 0)
                return "";
            return Encoding.Default.GetString(data);
        }


        public static string AsHexString(this byte[] ba)
        {
            if (ba == null || ba.Length == 0)
                return "";
            StringBuilder hex = new StringBuilder(ba.Length * 2);
            foreach (byte b in ba)
                hex.AppendFormat("{0:x2}", b);
            return hex.ToString();
        }

        public static string AsHexString(this byte[] ba, char c)
        {
            StringBuilder hex = new StringBuilder(ba.Length * 2);
            foreach (byte b in ba)
            {
                hex.AppendFormat("{0:x2}", b);
                hex.Append(c);
            }
            return hex.ToString().ToUpper();
        }

        public static string AsString(this byte[] data, Encoding encoding)
        {
            return encoding.GetString(data);
        }
    }
}